package com.cool.collect.springcode.a06;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor;
import org.springframework.context.annotation.CommonAnnotationBeanPostProcessor;
import org.springframework.context.annotation.ConfigurationClassPostProcessor;
import org.springframework.context.support.GenericApplicationContext;

/**
 * @author xiemiao
 * @description Aware接口以及InitializingBean接口
 * @date 2023/08/30
 */
public class A06Application {
    private static final Logger log = LoggerFactory.getLogger(A06Application.class);

    public static void main(String[] args) {
        /**
         * 1. Aware接口用于注入一些与容器相关信息，例如
         *   a. BeanNameAware注入bean的名字
         *   b. BeanFactoryAware注入BeanFactory容器
         *   c. ApplicationContextAware注入ApplicationContext容器
         *   d. EmbeddedValueResolverAware ${}
         */
        GenericApplicationContext context = new GenericApplicationContext();
        // context.registerBean("myBean", MyBean.class);
        context.registerBean("myConfig1", MyConfig1.class);
        context.registerBean("myConfig2", MyConfig2.class);
        context.registerBean(AutowiredAnnotationBeanPostProcessor.class);
        context.registerBean(CommonAnnotationBeanPostProcessor.class);
        context.registerBean(ConfigurationClassPostProcessor.class);

        /**
         * 2.
         * @Autowired的解析需要用到bean后处理器，属于扩展功能
         * Aware接口属于内置功能，不添加任何扩展，Spring就能识别
         * 某些情况下，扩展功能会失效，内置功能不会失效
         * 例1：用Aware注入ApplicationContext成功，而@Autowired注入ApplicaitionContext失败
         */

        /**
         * 例2：Java配置类在添加了bean工厂后处理器后，用传统接口方式的注入和初始化仍然成功，而@Autowired和@PostConstruct的注入和初始化失败
         */
        context.refresh(); // 1.beanFactory后处理器，2.添加bean处理器，3.初始化单例
        context.close();

        /**
         * Aware接口提供了一种内置的注入手段，可以注入BeanFactory,ApplicationContext
         * InitializingBean接口提供了一种内置的初始化手段
         * 内置的注入和初始化不受扩展功能的影响，总会被执行，因此Spring框架内部的类常用他们
         */
    }
}
